#include "video.hpp"
#include "menu.hpp"
#include "loader/sys.h"

#include "text.hpp"

#include <ogc/system.h>
#include <wiilight.h>

#include "gecko.h"
#include "devicemounter/DeviceHandler.hpp"

#include "defines.h"

extern "C"
{
    extern void __exception_setreload(int t);
	extern s32 MagicPatches(s32 enable);
}

extern const u8 wait_hdd_png[];

extern bool geckoinit;
extern bool bootHB;

CMenu *mainMenu;
extern "C" void ShowError(const wstringEx &error){mainMenu->error(error); }
extern "C" void HideWaitMessage() {mainMenu->_hideWaitMessage(); }

bool have_hw_access()
{
	return (*(volatile unsigned int*)HW_ARMIRQMASK && *(volatile unsigned int*)HW_ARMIRQFLAG);
}

int old_main(int, char **)
{
	geckoinit = InitGecko();
	__exception_setreload(5);

	int ret = 0;
	CVideo vid;


	u32 mainIOS = IOS_GetVersion();
	s32 preferred = IOS_GetPreferredVersion();

	gprintf("\nHave HW access? %s\n", have_hw_access() ? "YES!" : "NO!");
	gprintf("Main ios: %i\n", mainIOS);
	if(mainIOS != 58 && preferred > 0 && mainIOS != (u32)preferred && !have_hw_access())
	{
		gprintf("Reloading into: %i\n", preferred);
		IOS_ReloadIOS(preferred);
		mainIOS = IOS_GetVersion();
		gprintf("\nHave HW access # 2? %s\n", have_hw_access() ? "YES!" : "NO!");
		gprintf("Main ios: %i\n", mainIOS);
	}
	if(!have_hw_access())
	{
		gprintf("NO HW ACCESS! Exitting...");
		return 0;
	}
	MagicPatches(1); // We all love magic

	MEM2_init(36, 12);	// Max ~48

	vid.init();
	WIILIGHT_Init();
	Open_Inputs();
	vid.waitMessage(0.2f);

	// Init
	Sys_Init();
	Sys_ExitTo(1);

	do
	{
		MEM2_takeBigOnes(true);
		ISFS_Initialize();

		bool HddMounted = false;
		DeviceHandler::Instance()->MountSD();
		DeviceHandler::Instance()->MountAllUSB();
		for(int i = USB1; i <= USB8; i++)
			if(DeviceHandler::Instance()->IsInserted(i))
				HddMounted = true;

/*   		if(!HddMounted)
		{
			STexture texWaitHDD;
			texWaitHDD.fromPNG(wait_hdd_png, GX_TF_RGB565, ALLOC_MALLOC);
			vid.hideWaitMessage();
			vid.waitMessage(texWaitHDD);

			while(!HddMounted)
			{
				WPAD_ScanPads(); PAD_ScanPads();

				u32 wbtnsPressed = 0, gbtnsPressed = 0,
					wbtnsHeld = 0, gbtnsHeld = 0;

				for(int chan = WPAD_MAX_WIIMOTES-1; chan >= 0; chan--)
				{
					wbtnsPressed |= WPAD_ButtonsDown(chan);
					gbtnsPressed |= PAD_ButtonsDown(chan);

					wbtnsHeld |= WPAD_ButtonsHeld(chan);
					gbtnsHeld |= PAD_ButtonsHeld(chan);
				 }

				if (Sys_Exiting() || (wbtnsPressed & WBTN_HOME) || (gbtnsPressed & GBTN_HOME))
				{
					DeviceHandler::Instance()->UnMountSD();
					DeviceHandler::Instance()->UnMountAllUSB();
					Sys_ExitTo(1);
					Sys_Exit(0);
				}

				VIDEO_WaitVSync();
				VIDEO_WaitVSync();

				for(int i = USB1; i <= USB8; i++)
					if(DeviceHandler::Instance()->IsInserted(i))
						gprintf("%s is Available\n", DeviceName[i]);

				for(int i = USB1; i <= USB8; i++)
					if(DeviceHandler::Instance()->IsInserted(i))
						HddMounted = true;

				if(!HddMounted) DeviceHandler::Instance()->MountAllUSB();
			}
			vid.hideWaitMessage();
			vid.waitMessage(0.2f);
			SMART_FREE(texWaitHDD.data);
		}


		for(int i = 0; i < MAXDEVICES; i++)
			if(DeviceHandler::Instance()->IsInserted(i))
			{
				HddMounted = true;
				gprintf("%s is Available\n", DeviceName[i]);
			}
*/
		if(!HddMounted)
		{
			DeviceHandler::Instance()->UnMountAllUSB();
			DeviceHandler::Instance()->MountAllUSB();
			for(int i = 1; i < MAXDEVICES; i++)
				if(DeviceHandler::Instance()->IsInserted(i))
					gprintf("%s is Available\n", DeviceName[i]);
		}

		CMenu menu(vid);
		menu.init();
		mainMenu = &menu;
		ret = menu.main();
		vid.cleanup();

		DeviceHandler::Instance()->UnMountSD();
		DeviceHandler::Instance()->UnMountAllUSB();
		//Close_Inputs();
		//USB_Deinitialize();
		if (bootHB)	BootHomebrew();
		else if(ret == 1) Open_Inputs();
	} while (ret == 1);
	return ret;
};

int main(int argc, char **argv)
{
	Sys_Exit(old_main(argc, argv));
	return 0;
}

